﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.Commands;
using Microsoft.Practices.CompositeUI.SmartParts;
using Microsoft.Practices.ObjectBuilder;
using WPFCABShell.Shell.Interface.Services.Command;
using WPFCABCommands = WPFCABShell.Shell.Interface.Services.Command;

namespace WPFCABShell.$safeprojectname$
{
	public partial class CommandVisualizer : UserControl
	{
		private readonly IVisualizer _visualizer;

		private static readonly DependencyPropertyKey _executionHistoryPropertyKey = DependencyProperty.RegisterReadOnly("ExecutionHistory",
			typeof(ObservableCollection<HistoryEntry>),
			typeof(CommandVisualizer),
			new FrameworkPropertyMetadata());

		public static readonly DependencyProperty ExecutionHistoryProperty = _executionHistoryPropertyKey.DependencyProperty;

		public static readonly DependencyProperty ExecutionCountProperty = DependencyProperty.RegisterAttached("ExecutionCount",
			typeof(int),
			typeof(CommandVisualizer));

		public static readonly DependencyProperty LastExecutionTimestampProperty = DependencyProperty.RegisterAttached("LastExecutionTimestamp",
			typeof(DateTime?),
			typeof(CommandVisualizer));

		public ObservableCollection<HistoryEntry> ExecutionHistory
		{
			get
			{
				return GetValue(ExecutionHistoryProperty) as ObservableCollection<HistoryEntry>;
			}
			private set
			{
				SetValue(_executionHistoryPropertyKey, value);
			}
		}

		public ICommandService CommandService
		{
			get
			{
				return _visualizer.CabRootWorkItem.Services.Get<ICommandService>();
			}
		}

		public CommandVisualizer()
		{
			InitializeComponent();
		}

		[InjectionConstructor]
		public CommandVisualizer(WorkItem rootWorkItem, IVisualizer visualizer)
			: this()
		{
			_visualizer = visualizer;
			//this will show our visualizer in the main visualizer window
			rootWorkItem.Workspaces["MainWorkspace"].Show(this, new SmartPartInfo("Command Visualizer", string.Empty));
			ExecutionHistory = new ObservableCollection<HistoryEntry>();
			Loaded += CommandVisualizer_Loaded;
		}

		public static int GetExecutionCount(DependencyObject obj)
		{
			return (int)obj.GetValue(ExecutionCountProperty);
		}

		public static void SetExecutionCount(DependencyObject obj, int value)
		{
			obj.SetValue(ExecutionCountProperty, value);
		}

		public static DateTime? GetLastExecutionTimestamp(DependencyObject obj)
		{
			return (DateTime?)obj.GetValue(LastExecutionTimestampProperty);
		}

		public static void SetLastExecutionTimestamp(DependencyObject obj, DateTime? value)
		{
			obj.SetValue(LastExecutionTimestampProperty, value);
		}

		private void CommandVisualizer_Loaded(object senderIgnore, RoutedEventArgs eIgnore)
		{
			Loaded -= CommandVisualizer_Loaded;

			CommandService.CommandExecuted += delegate(object sender, CommandEventArgs e)
			{
				HistoryEntry historyEntry = new HistoryEntry(e.Command);
				ExecutionHistory.Add(historyEntry);

				DependencyObject container = _registeredCommandsListView.ItemContainerGenerator.ContainerFromItem(e.Command);

				if (container != null)
				{
					SetExecutionCount(container, GetExecutionCount(container) + 1);
					SetLastExecutionTimestamp(container, historyEntry.Timestamp);
				}
			};

			DataContext = this;
		}

		public sealed class HistoryEntry
		{
			private readonly WPFCABCommands.ICommand _command;
			private readonly DateTime _timestamp;

			public WPFCABCommands.ICommand Command
			{
				get
				{
					return _command;
				}
			}

			public DateTime Timestamp
			{
				get
				{
					return _timestamp;
				}
			}

			internal HistoryEntry(WPFCABCommands.ICommand command)
			{
				_command = command;
				_timestamp = DateTime.Now;
			}
		}
	}
}
